/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tbquestion_client.form;

import bllobjects.Account;
import chat.ChatMessage;
import chat.TextChatMessage;
import chat.sound.SoundFocusListener;
import fsktms.request.IRequestDelegate;
import fsktms.request.Request;
import fsktms.request.RequestParameters;
import fsktms.request.RequestRespond;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.text.DefaultCaret;
import model.ClientModel;
import model.chat.ChatMessageModel;
import qclient.QClient;

/**
 *
 * @author Mrkupi
 */
public class privateChat extends javax.swing.JFrame implements ListDataListener, SoundFocusListener
{
    private Account friend;
    private ChatMessageModel messageModel;
    
    /**
     * Creates new form privateChat
     */
    public privateChat(Account fr) {
        initComponents();
        
        setResizable(false);
        this.friend = fr;
        
        this.initWindowCustomize();
        this.loadUserInfo();
        this.loadConversationHistory();
    }
    
    private void initWindowCustomize() {

        taChatBox.setWrapStyleWord(true);
        DefaultCaret dc = (DefaultCaret) taChatBox.getCaret();
        dc.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
    }

    private void loadUserInfo() {
        this.lblFriendName.setText(friend.getUserName());
        this.lblTitle.setText("CHAT " + friend.getUserName().toUpperCase());
        ClientModel.getInstance().getSoundChatManager().getListeners().add(this);
    }
    
    private void loadConversationHistory()
    {
        this.messageModel = ClientModel.getInstance().getMessageModels().get(friend.getUserID());
        if (this.messageModel != null)
        {
            this.messageModel.addListDataListener(this);
            this.reloadAllMessages();
            return;
        }
        try
        {
            RequestParameters params = new RequestParameters()
                    .set(RequestParameters.KEY_FUNCTION, "getConversation")
                    .set("User1", ClientModel.getInstance().getAccount().getUserID())
                    .set("User2", friend.getUserID());
            final privateChat copyThis = this;
            QClient.getInstance().getRequestManager().sendRequest(new Request(
                    "Chat", params, new IRequestDelegate() {

                @Override
                public void requestCompleted(RequestRespond respond) {
                    if (respond.isSuccess())
                    {
                        ArrayList<TextChatMessage> messages = (ArrayList<TextChatMessage>) respond.getResult();
                        messageModel = new ChatMessageModel(messages);
                        messageModel.addListDataListener(copyThis);
                        ClientModel.getInstance().getMessageModels().put(friend.getUserID(), messageModel);
                        copyThis.reloadAllMessages(); 
                    }
                }
            }));
        } catch (IOException ex) {
            Logger.getLogger(worldChat.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    @Override
    public void dispose()
    {
        if (this.messageModel != null)
        {
            this.messageModel.removeListDataListener(this);
        }
        ClientModel.getInstance().getSoundChatManager().getListeners().remove(this);
        if (friend.getUserID().equals(ClientModel.getInstance().getSoundChatManager().getFocusID()))
        {
            ClientModel.getInstance().getSoundChatManager().setFocusID(null, false);
        }
        
        super.dispose();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblTitle = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        taChatBox = new javax.swing.JTextArea();
        tfChat = new javax.swing.JTextField();
        btEnter = new javax.swing.JButton();
        lblFriendName = new javax.swing.JLabel();
        btnSound = new javax.swing.JButton();
        btnFriendAvatar = new javax.swing.JButton();
        btnMyAvatar = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("PRIVATE CHAT");

        lblTitle.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        lblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblTitle.setText("CHAT");

        taChatBox.setEditable(false);
        taChatBox.setColumns(20);
        taChatBox.setRows(5);
        jScrollPane1.setViewportView(taChatBox);

        tfChat.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                onEnter_pressed(evt);
            }
        });

        btEnter.setText("Enter");
        btEnter.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                onEnter_clicked(evt);
            }
        });

        lblFriendName.setText("Name");

        btnSound.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/voice-support copy.png"))); // NOI18N
        btnSound.setText("Sound: Mute");
        btnSound.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSoundActionPerformed(evt);
            }
        });

        btnFriendAvatar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/popo_emotions_full_version boss copy.png"))); // NOI18N

        btnMyAvatar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/popo_emotions_full_version boss copy.png"))); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(lblTitle, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(tfChat)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(btEnter, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(btnSound, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnFriendAvatar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(btnMyAvatar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(lblFriendName, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(23, 23, 23)
                .addComponent(lblTitle)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(lblFriendName)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnFriendAvatar, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnMyAvatar, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tfChat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btEnter)
                    .addComponent(btnSound, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(21, 21, 21))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void onEnter_pressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_onEnter_pressed
        if( evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER )
            this.sendMessageToFriend();
    }//GEN-LAST:event_onEnter_pressed

    private void onEnter_clicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_onEnter_clicked
        this.sendMessageToFriend();
    }//GEN-LAST:event_onEnter_clicked

    private void btnSoundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSoundActionPerformed
        if (friend.getUserID().equals(ClientModel.getInstance().getSoundChatManager().getFocusID()))
        {
            ClientModel.getInstance().getSoundChatManager().setFocusID(null, false);
        }
        else
        {
            ClientModel.getInstance().getSoundChatManager().setFocusID(friend.getUserID(), true);
        }
    }//GEN-LAST:event_btnSoundActionPerformed

    
    private boolean makeSureNotEmptyTextField()
    {
        if( "".equals( tfChat.getText() ))
        {
            JOptionPane.showMessageDialog( this, "" );
            return false;
        }
        
        return true;
    }
    
    private void publishNewMessageToTextArea( String message )
    {
        this.taChatBox.append( message );
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btEnter;
    private javax.swing.JButton btnFriendAvatar;
    private javax.swing.JButton btnMyAvatar;
    private javax.swing.JButton btnSound;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblFriendName;
    private javax.swing.JLabel lblTitle;
    private javax.swing.JTextArea taChatBox;
    private javax.swing.JTextField tfChat;
    // End of variables declaration//GEN-END:variables

    
    @Override
    public void intervalAdded(ListDataEvent e) {
        for (int i = e.getIndex0(); i < e.getIndex1(); ++i)
        {
            TextChatMessage chatMsg = (TextChatMessage) messageModel.getElementAt(i);
            this.appendMessage(chatMsg);
        }
    }

    @Override
    public void intervalRemoved(ListDataEvent e) {
        this.reloadAllMessages();
    }

    @Override
    public void contentsChanged(ListDataEvent e) {
        this.reloadAllMessages();
    }
    
    private void appendMessage(TextChatMessage chatMsg)
    {
        this.taChatBox.append(chatMsg + "\n");
        System.out.println("Append message " + chatMsg);
    }
    
    private void reloadAllMessages()
    {
        System.out.println("Reload all messages, nMessage " + messageModel.getSize());
        this.taChatBox.setText(null);
        for (int i = 0; i < messageModel.getSize(); ++i)
        {
            TextChatMessage chatMsg = (TextChatMessage) messageModel.getElementAt(i);
            this.appendMessage(chatMsg);
        }
        System.out.println("Reload all messages completed");
    }
    
    private boolean sendMessageToFriend()
    {
        if( !makeSureNotEmptyTextField() )
            return false;
        try
        {
            String msgContent = this.tfChat.getText();
            this.tfChat.setText(null);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            TextChatMessage chatMsg = new TextChatMessage(
                    ClientModel.getInstance().getAccount().getUserID(),
                    friend.getUserID(),
                    msgContent);
            oos.writeObject(chatMsg);
            QClient.getInstance().getNetClient().sendMessage(bos.toByteArray(), 
                    ChatMessage.CHAT_MESSAGE_MAGICKEY);
            this.messageModel.addMessage(chatMsg);
        }
        catch (IOException ex)
        {
            
        }
        
        return false;
    }

    @Override
    public void onFocusChanged(String focus, String oldFocus)
    {
        if (friend.getUserID().equals(focus))
        {
            this.btnSound.setText("Sound: Active");
        }
        else
        {
            this.btnSound.setText("Sound: Muted");
        }
    }

    @Override
    public void becomeTalker(String talkerID) {
        
    }
}
